﻿#region License
// (c) Intergen.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using TextGlow.Control.Utilities;

namespace TextGlow.Control.Controls.Document
{
  public partial class TableControl : UserControlExtended
  {
    private double _indentLeft;

    public double IndentLeft
    {
      get { return _indentLeft; }
      set { _indentLeft = value; }
    }

    public UIElementCollection Rows
    {
      get { return RowContainer.Children; }
    }
    
    public TableControl()
    {
      InitializeComponent();

      HorizontalAlignment = HorizontalAlignment.Left;
    }

    private double CalculateTableWidth(double width)
    {
      return width - _indentLeft;
    }

    protected override Size CustomMeasureOverride(Size availableSize)
    {
      RowContainer.CustomMeasure(new Size(CalculateTableWidth(availableSize.Width), availableSize.Height));

      return RowContainer.CustomDesiredSize;
    }

    protected override Size CustomArrangeOverride(Size finalSize)
    {
      Rect rowRect = LayoutUtils.CreateRect(new Point(0, 0), new Size(CalculateTableWidth(finalSize.Width), finalSize.Height));
      RowContainer.CustomArrange(rowRect);
      RowContainer.SetValue(Canvas.LeftProperty, _indentLeft);

      FixedCellHeights();
      RowContainer.CustomMeasure(finalSize);
      RowContainer.CustomArrange(rowRect);

      return RowContainer.CustomDesiredSize;
    }

    //protected override void PerformLayout()
    //{
    //  _rowContainer.SetValue(Canvas.LeftProperty, _indentLeft);
    //  _rowContainer.AutoSize = AutoSize.Both;
    //  _rowContainer.UpdateLayout();

    //  FixedCellHeights();

    //  Height = _rowContainer.Height;
    //  Width = _rowContainer.Width;
    //}

    private double CalculateCellHeight(int rowIndex, int rowSpan)
    {
      return RowContainer.Children
        .Select((v, i) => new { Row = (TableRowControl)v, Index = i })
        .Where(o => o.Index >= rowIndex && o.Index < rowIndex + rowSpan)
        .Sum(o => o.Row.Height);
    }

    private void FixedCellHeights()
    {
      for (int i = 0; i < RowContainer.Children.Count; i++)
      {
        TableRowControl row = (TableRowControl)RowContainer.Children[i];

        foreach (TableCellControl cell in row.CellContainer.Children)
        {
          //cell.AutoSize = AutoSize.None;
          cell.Height = CalculateCellHeight(i, cell.RowSpan);
          //cell.UpdateLayout();
        }
      }
    }

    public double CalculateRowHeight(int rowIndex)
    {
      double height = 0;
      double endSpanHeight = 0;

      for (int i = 0; i <= rowIndex; i++)
      {
        TableRowControl row = (TableRowControl)RowContainer.Children[i];

        int rowSpan = rowIndex - i + 1;
        double? rowSpanMaxHeight = row.GetRowSpanMaxHeight(rowSpan);
        if (rowSpanMaxHeight != null)
          endSpanHeight = Math.Max(endSpanHeight, rowSpanMaxHeight.Value);

        height += row.Height;
        if (rowSpan > 1)
          endSpanHeight -= row.Height;
      }

      return endSpanHeight;
    }
  }
}
